package com.ultrapower.util.topology;

import com.ultrapower.bean.ApplicationBean;

public class LinkData {

	    private final ApplicationBean fromApplication;
	    private final ApplicationBean toApplication;

	    private LinkCallDataMap linkCallDataMap;
	    private final TimeWindow timeWindow;

	    public LinkData(ApplicationBean fromApplication, ApplicationBean toApplication) {
	        this(fromApplication, toApplication, null);
	    }
	    public LinkData(ApplicationBean fromApplication, ApplicationBean toApplication, TimeWindow timeWindow) {
	        if (fromApplication == null) {
	            throw new NullPointerException("fromApplication must not be null");
	        }
	        if (toApplication == null) {
	            throw new NullPointerException("toApplication must not be null");
	        }

	        this.fromApplication = fromApplication;
	        this.toApplication = toApplication;

	        this.timeWindow = timeWindow;
	        this.linkCallDataMap = new LinkCallDataMap(timeWindow);
	    }

	    /**
	     *
	     * @param hostname
	     *            host name or endpoint
	     * @param slot
	     * @param count
	     */
	    public void addLinkData(String callerAgentId, short callerServiceTypeCode, String hostname, short serviceTypeCode, long timestamp, short slot, long count) {
	        if (hostname == null) {
	            throw new NullPointerException("hostname must not be null");
	        }
	        this.linkCallDataMap.addCallData(callerAgentId, callerServiceTypeCode, hostname, serviceTypeCode, timestamp, slot, count);
	    }

	    public void resetLinkData() {
	        this.linkCallDataMap = new LinkCallDataMap(timeWindow);
	    }


	    public ApplicationBean getFromApplication() {
	        return this.fromApplication;
	    }

	    public ApplicationBean getToApplication() {
	        return this.toApplication;
	    }

	    public void setLinkCallDataMap(LinkCallDataMap linkCallDataMap) {
	        this.linkCallDataMap = linkCallDataMap;
	    }

	    public LinkCallDataMap getLinkCallDataMap() {
	        return  this.linkCallDataMap;
	    }

	    public AgentHistogramList getTargetList() {
	        return linkCallDataMap.getTargetList();
	    }

	    public AgentHistogramList getSourceList() {
	        return linkCallDataMap.getSourceList();
	    }

	    public void add(final LinkData linkData) {
	        if (linkData == null) {
	            throw new NullPointerException("linkData must not be null");
	        }
	        if (!this.equals(linkData)) {
	            throw new IllegalArgumentException("Can't merge with different link.");
	        }
	        final LinkCallDataMap target = linkData.linkCallDataMap;
	        this.linkCallDataMap.addLinkDataMap(target);
	    }

	    // test api
	    public long getTotalCount() {
	        long totalCount = 0;
	        for (LinkCallData linkCallData : linkCallDataMap.getLinkDataList()) {
	            totalCount += linkCallData.getTotalCount();
	        }
	        return totalCount;
	    }

	    @Override
	    public String toString() {
	        return "LinkData{" +
	                "fromApplication=" + fromApplication +
	                ", toApplication=" + toApplication +
	                ", " + linkCallDataMap +
	                '}';
	    }

	    @Override
	    public boolean equals(Object o) {
	        if (this == o) return true;
	        if (o == null || getClass() != o.getClass()) return false;

	        LinkData that = (LinkData) o;

	        if (!fromApplication.equals(that.fromApplication)) return false;
	        if (!toApplication.equals(that.toApplication)) return false;

	        return true;
	    }

	    @Override
	    public int hashCode() {
	        int result = fromApplication.hashCode();
	        result = 31 * result + toApplication.hashCode();
	        return result;
	    }
	    
	    public TimeWindow getTimeWindow() {
		return this.timeWindow;
	}
}
